{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fd60760f-7373-43d5-b5be-6d790bee6f0d",
   "metadata": {},
   "source": [
    "## 2412114336-陈铭-实验2-0916"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "622433f8-155d-48f8-8fd3-040627739f44",
   "metadata": {},
   "source": [
    "任务1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a71e3657-0fa6-4d70-9fb0-c31b439e8495",
   "metadata": {},
   "outputs": [],
   "source": [
    "# coding=utf8\n",
    "\n",
    "class BaseConverter:\n",
    "    def __init__(self, num: int):\n",
    "        self.num = num\n",
    "\n",
    "    def convert(self, base: int) -> str:\n",
    "        if base not in (2, 8):\n",
    "            raise ValueError(\"只支持二进制或八进制转换！\")\n",
    "\n",
    "        result = []\n",
    "        div = self.num\n",
    "        while div != 0:\n",
    "            div, mod = divmod(div, base)\n",
    "            result.append(mod)\n",
    "\n",
    "        result.reverse()\n",
    "        return ' '.join(map(str, result))\n",
    "\n",
    "    def show_result(self, base: int):\n",
    "        converted = self.convert(base)\n",
    "        print(f\"十进制数：{self.num} = ({converted}) {base}进制\")\n",
    "\n",
    "\n",
    "def main():\n",
    "    num = int(input(\"请输入十进制整数：\"))\n",
    "    while True:\n",
    "        try:\n",
    "            n = int(input(\"请输入转换进制：\"))\n",
    "            assert n == 2 or n == 8\n",
    "            break\n",
    "        except:\n",
    "            print(\"输入错误！\")\n",
    "\n",
    "    converter = BaseConverter(num)\n",
    "    converter.show_result(n)\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0e45033-4385-4635-8d56-5e97d4d33cca",
   "metadata": {},
   "source": [
    "任务2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3fc4beb-26da-4f43-92dd-a2b972242c28",
   "metadata": {},
   "outputs": [],
   "source": [
    "# coding=utf8\n",
    "import datetime\n",
    "import time\n",
    "\n",
    "\n",
    "class ClockReminder:\n",
    "    def __init__(self, hour: int, minute: int):\n",
    "        self.hour = hour\n",
    "        self.minute = minute\n",
    "\n",
    "    def warning(self):\n",
    "        print(f\"{datetime.datetime.now()} 哥们，要微哨打卡啦...\")\n",
    "\n",
    "    def wait_until_time(self):\n",
    "        \"\"\"循环等待到设定的时间\"\"\"\n",
    "        while True:\n",
    "            now = datetime.datetime.now()\n",
    "            if now.hour == self.hour and now.minute == self.minute:\n",
    "                break\n",
    "            else:\n",
    "                time.sleep(60)  # 不是设定时间就等一分钟再检查\n",
    "\n",
    "    def start(self):\n",
    "        \"\"\"开始定时提醒\"\"\"\n",
    "        while True:\n",
    "            self.wait_until_time()\n",
    "            self.warning()\n",
    "            time.sleep(60)  # 避免一分钟内重复提醒\n",
    "\n",
    "\n",
    "def main():\n",
    "    reminder = ClockReminder(8, 52)  # 设定每天9点08分提醒\n",
    "    reminder.start()\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b997611-9e71-4c08-aea6-e8c175005fdb",
   "metadata": {},
   "source": [
    "任务3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f9d0891-cdf2-4457-81b1-51fc94d95ac0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# coding=utf8\n",
    "import time\n",
    "\n",
    "\n",
    "def get_factors(n: int):\n",
    "    \"\"\"返回 n 的真因子列表\"\"\"\n",
    "    return [j for j in range(1, n // 2 + 1) if n % j == 0]\n",
    "\n",
    "\n",
    "def find_perfect_numbers(limit: int):\n",
    "    \"\"\"查找 limit 以内的完全数\"\"\"\n",
    "    perfect_numbers = []\n",
    "    for i in range(2, limit + 1):\n",
    "        factors = get_factors(i)\n",
    "        if i == sum(factors):\n",
    "            perfect_numbers.append((i, factors))\n",
    "    return perfect_numbers\n",
    "\n",
    "\n",
    "def main():\n",
    "    start = time.time()\n",
    "    results = find_perfect_numbers(1000)\n",
    "    if results:\n",
    "        for num, factors in results:\n",
    "            print(f\"{num} 是完全数，真因子为 {factors}\")\n",
    "    else:\n",
    "        print(\"没有找到完全数。\")\n",
    "    end = time.time()\n",
    "    print(\"计算完成，共用时 %.3f 秒\" % (end - start))\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1085e528-2ed3-4387-94de-0259d88dfa89",
   "metadata": {},
   "source": [
    "任务4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6643b676-e777-439c-a75c-18482be71cc5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入评委人数： 5\n",
      "请输入第 1 个评委的分数 (0~10)： 100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "分数错误！请重新输入。\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入第 1 个评委的分数 (0~10)： 9\n",
      "请输入第 2 个评委的分数 (0~10)： 5\n",
      "请输入第 3 个评委的分数 (0~10)： 4\n",
      "请输入第 4 个评委的分数 (0~10)： 8\n",
      "请输入第 5 个评委的分数 (0~10)： 7\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------评委打的原始分--------------------------- \n",
      " [9.0, 5.0, 4.0, 8.0, 7.0]\n",
      "----------------------去掉最高分和最低分后的分数---------------------- \n",
      " [5.0, 8.0, 7.0]\n",
      "-------------------------------最后得分------------------------------ \n",
      " 6.667\n"
     ]
    }
   ],
   "source": [
    "# coding=utf8\n",
    "from copy import deepcopy\n",
    "\n",
    "\n",
    "class JudgeScoring:\n",
    "    def __init__(self):\n",
    "        self.scores = []\n",
    "        self.num_judges = 0\n",
    "\n",
    "    def input_judges(self):\n",
    "        \"\"\"输入评委人数\"\"\"\n",
    "        while True:\n",
    "            try:\n",
    "                num = int(input(\"请输入评委人数：\"))\n",
    "                if num <= 2:\n",
    "                    print(\"评委人数太少，必须多于 2 人！\")\n",
    "                else:\n",
    "                    self.num_judges = num\n",
    "                    break\n",
    "            except ValueError:\n",
    "                print(\"输入无效，请输入整数！\")\n",
    "\n",
    "    def input_scores(self):\n",
    "        \"\"\"输入每个评委的打分\"\"\"\n",
    "        for i in range(self.num_judges):\n",
    "            while True:\n",
    "                try:\n",
    "                    score = float(input(f\"请输入第 {i + 1} 个评委的分数 (0~10)：\"))\n",
    "                    assert 0 <= score <= 10\n",
    "                    self.scores.append(score)\n",
    "                    break\n",
    "                except (ValueError, AssertionError):\n",
    "                    print(\"分数错误！请重新输入。\")\n",
    "\n",
    "    def calculate_score(self):\n",
    "        \"\"\"计算去掉最高分和最低分后的平均分\"\"\"\n",
    "        scores_copy = deepcopy(self.scores)\n",
    "        highest = max(scores_copy)\n",
    "        lowest = min(scores_copy)\n",
    "        scores_copy.remove(highest)\n",
    "        scores_copy.remove(lowest)\n",
    "        mean_score = round(sum(scores_copy) / len(scores_copy), 3)\n",
    "        return highest, lowest, mean_score, scores_copy\n",
    "\n",
    "    def run(self):\n",
    "        self.input_judges()\n",
    "        self.input_scores()\n",
    "        highest, lowest, mean_score, filtered_scores = self.calculate_score()\n",
    "\n",
    "        print(\"评委打的原始分\".center(60, '-'), '\\n', self.scores)\n",
    "        print(\"去掉最高分和最低分后的分数\".center(57, '-'), '\\n', filtered_scores)\n",
    "        print(\"最后得分\".center(65, '-'), '\\n', mean_score)\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    JudgeScoring().run()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c6ef736-325e-42a0-bc51-3e67c22af938",
   "metadata": {},
   "source": [
    "任务5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "33d0d7cc-2576-4e91-9146-666ba4079cbe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你包红包的总金额(1-200)： 100\n",
      "请输入抢红包的人数： 4\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-------------------------红包分发结果如下：--------------------------\n",
      "[30.97, 14.03, 0.24, 54.76]\n",
      "总和： 100.0\n"
     ]
    }
   ],
   "source": [
    "# coding=utf8\n",
    "import random as rd\n",
    "\n",
    "def redLuckyMoney(amount, num):  # amount 为拟发红包金额，num 为抢红包的人数\n",
    "    moneys = []  # 存放每个红包大小\n",
    "    total = 0\n",
    "    for x in range(1, num):  # 先分 num-1 个红包\n",
    "        while True:\n",
    "            try:\n",
    "                # 保证每个红包至少 0.1，剩下的钱足够给后面的人\n",
    "                one = round(rd.uniform(0.1, (amount - total) - (num - x) * 0.1), 2)\n",
    "                assert 0 <= one <= (3 * amount / num)\n",
    "                break\n",
    "            except:\n",
    "                continue\n",
    "        moneys.append(one)\n",
    "        total += one\n",
    "    \n",
    "    # 最后一个红包 = 剩余金额\n",
    "    last = round(amount - total, 2)\n",
    "    moneys.append(last)\n",
    "    return moneys\n",
    "\n",
    "\n",
    "def main():\n",
    "    while True:\n",
    "        try:\n",
    "            amount = int(input(\"请输入你包红包的总金额(1-200)：\"))\n",
    "            assert 1 <= amount <= 200\n",
    "            break\n",
    "        except:\n",
    "            print(\"输入错误！\")\n",
    "    \n",
    "    while True:\n",
    "        try:\n",
    "            num = int(input(\"请输入抢红包的人数：\"))\n",
    "            assert 1 <= num <= 100\n",
    "            break\n",
    "        except:\n",
    "            print(\"输入错误！\")\n",
    "    \n",
    "    result = redLuckyMoney(amount, num)\n",
    "    print(\"红包分发结果如下：\".center(60, '-'))\n",
    "    print(result)\n",
    "    print(\"总和：\", round(sum(result), 2))  # 校验是否等于总金额\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95730c77-3930-4fdc-9e45-752b711aae41",
   "metadata": {},
   "source": [
    "任务6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b3ea9025-4c05-43fb-a373-34c089a3331a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "------------用户管理系统------------\n",
      "1.添加  2.删除  3.显示  0.退出\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请选择： 1\n",
      "请输入用户名： 王源\n",
      "请输入密码： 110023\n",
      "添加成功，继续？(Y/N) y\n",
      "请输入用户名： 蔡徐坤\n",
      "请输入密码： 110023\n",
      "添加成功，继续？(Y/N) y\n",
      "请输入用户名： 管理员\n",
      "请输入密码： root\n",
      "添加成功，继续？(Y/N) n\n",
      "请选择： 3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      用户信息      \n",
      "----------------\n",
      "| 用户名  | 密码       |\n",
      "----------------\n",
      "| 王源  | 110023 |\n",
      "| 蔡徐坤 | 110023 |\n",
      "| 管理员 | root   |\n",
      "----------------\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请选择： 0\n"
     ]
    }
   ],
   "source": [
    "#coding=utf8\n",
    "users = {}\n",
    "\n",
    "def readFile(file):\n",
    "    \"\"\"读取用户信息，兼容多种编码\"\"\"\n",
    "    try:\n",
    "        # 尝试多种编码读取，解决解码错误\n",
    "        for encoding in ['utf-8', 'gbk', 'latin-1']:\n",
    "            try:\n",
    "                with open(file, \"r+\", encoding=encoding) as fp:\n",
    "                    for line in fp:\n",
    "                        line = line.strip()\n",
    "                        if ',' in line:\n",
    "                            u, p = line.split(',', 1)\n",
    "                            users[u.strip()] = p.strip()\n",
    "                return users\n",
    "            except UnicodeDecodeError:\n",
    "                continue\n",
    "        # 所有编码尝试失败则创建新文件\n",
    "        open(file, \"w\").close()\n",
    "    except FileNotFoundError:\n",
    "        open(file, \"w\").close()\n",
    "    return users\n",
    "\n",
    "def saveFile(file):\n",
    "    \"\"\"保存用户信息\"\"\"\n",
    "    with open(file, \"w\", encoding=\"utf-8\") as fp:\n",
    "        fp.writelines(f\"{k},{v}\\n\" for k, v in users.items())\n",
    "\n",
    "def add_user():\n",
    "    \"\"\"添加用户\"\"\"\n",
    "    while True:\n",
    "        u = input(\"请输入用户名：\").strip()\n",
    "        if not u:\n",
    "            print(\"用户名不能为空！\")\n",
    "            continue\n",
    "        if u in users:\n",
    "            print(\"用户已存在！\")\n",
    "            continue\n",
    "        p = input(\"请输入密码：\").strip()\n",
    "        if not p:\n",
    "            print(\"密码不能为空！\")\n",
    "            continue\n",
    "        users[u] = p\n",
    "        saveFile(\"users.csv\")\n",
    "        if input(\"添加成功，继续？(Y/N)\").lower() != 'y':\n",
    "            break\n",
    "\n",
    "def delete_user():\n",
    "    \"\"\"删除用户\"\"\"\n",
    "    while True:\n",
    "        u = input(\"请输入要删除的用户名：\").strip()\n",
    "        if not u:\n",
    "            print(\"用户名不能为空！\")\n",
    "            continue\n",
    "        if u in users:\n",
    "            if input(\"确定删除？(Y/N)\").lower() == 'y':\n",
    "                del users[u]\n",
    "                saveFile(\"users.csv\")\n",
    "                print(\"已删除！\")\n",
    "                if input(\"继续删除？(Y/N)\").lower() != 'y':\n",
    "                    break\n",
    "            else:\n",
    "                break\n",
    "        else:\n",
    "            if input(\"用户不存在，重新输入？(Y/N)\").lower() != 'y':\n",
    "                break\n",
    "\n",
    "def display_user():\n",
    "    \"\"\"显示用户\"\"\"\n",
    "    if not users:\n",
    "        print(\"无用户信息\")\n",
    "        return\n",
    "    max_u = max(len(u) for u in users)\n",
    "    max_p = max(len(p) for p in users.values())\n",
    "    w = max_u + max_p + 7\n",
    "    print(\"用户信息\".center(w))\n",
    "    print('-' * w)\n",
    "    print(f\"| 用户名{' '*(max_u-2)} | 密码{' '*(max_p)} |\")\n",
    "    print('-' * w)\n",
    "    for u, p in users.items():\n",
    "        print(f\"| {u.ljust(max_u)} | {p.ljust(max_p)} |\")\n",
    "    print('-' * w)\n",
    "\n",
    "def menu():\n",
    "    \"\"\"主菜单\"\"\"\n",
    "    print(\"用户管理系统\".center(30, '-'))\n",
    "    print(\"1.添加  2.删除  3.显示  0.退出\")\n",
    "    while True:\n",
    "        c = input(\"请选择：\")\n",
    "        if c == '1':\n",
    "            add_user()\n",
    "        elif c == '2':\n",
    "            delete_user()\n",
    "        elif c == '3':\n",
    "            display_user()\n",
    "        elif c == '0':\n",
    "            break\n",
    "        else:\n",
    "            print(\"输入错误！\")\n",
    "\n",
    "def main():\n",
    "    readFile(\"users.csv\")\n",
    "    menu()\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3a8698b-d8a8-45fa-8e62-11d488897cfc",
   "metadata": {},
   "source": [
    "任务7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4f8154c1-7cb6-4d86-8af4-b80f593c7a28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "输入用户名： root\n",
      "请输入密码： Poot\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "登录成功！\n",
      "判断用户是否具有权限.\n",
      "用户 root 没有权限！\n"
     ]
    }
   ],
   "source": [
    "# wrapper.py\n",
    "# coding=utf-8\n",
    "\n",
    "# 模拟一个用户数据库\n",
    "user_db = {\n",
    "    \"root\": \"Poot\",      # 没权限的用户\n",
    "    \"admin\": \"admin\",    # 有权限的用户\n",
    "    \"test\": \"123456\"     # 其他用户\n",
    "}\n",
    "\n",
    "# 模拟权限表\n",
    "permission_db = {\n",
    "    \"admin\": True,\n",
    "    \"root\": False,\n",
    "    \"test\": False\n",
    "}\n",
    "\n",
    "# 当前登录用户\n",
    "current_user = {\"username\": None}\n",
    "\n",
    "\n",
    "# 登录装饰器：确保用户已登录\n",
    "def login_required(func):\n",
    "    def wrapper(*args, **kwargs):\n",
    "        if current_user[\"username\"] is None:\n",
    "            username = input(\"输入用户名：\")\n",
    "            password = input(\"请输入密码：\")\n",
    "            # 用户名是否存在\n",
    "            if username not in user_db:\n",
    "                print(\"该用户不存在！\")\n",
    "                return None\n",
    "            # 验证密码\n",
    "            if user_db[username] != password:\n",
    "                print(\"密码错误！\")\n",
    "                return None\n",
    "            # 登录成功\n",
    "            current_user[\"username\"] = username\n",
    "            print(\"登录成功！\")\n",
    "        return func(*args, **kwargs)\n",
    "    return wrapper\n",
    "\n",
    "\n",
    "# 权限装饰器：确保用户有权限\n",
    "def permission_required(func):\n",
    "    def wrapper(*args, **kwargs):\n",
    "        username = current_user[\"username\"]\n",
    "        print(\"判断用户是否具有权限.\")\n",
    "        if not permission_db.get(username, False):\n",
    "            print(f\"用户 {username} 没有权限！\")\n",
    "            return None\n",
    "        return func(*args, **kwargs)\n",
    "    return wrapper\n",
    "\n",
    "\n",
    "# 删除信息功能，叠加两个装饰器\n",
    "@login_required\n",
    "@permission_required\n",
    "def delete_info():\n",
    "    print(\"正在删除信息..\")\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    delete_info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64839f5e-d5e9-4933-bff0-648a6b4b01ca",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
